/**
 * @author yangjian (1171267147@qq.com)
 * @brief linked_list.hpp单元测试
 * @version 1.0.0
 * @date 2024/07/27
 * @copyright Copyright (c) 2024 yangjian.
 */

#include <gtest/gtest.h>

#include "stl/container/linked_list.hpp"

using stl::LinkedList;

TEST(LinkedListTest, Init) {
    LinkedList<int> list;
    EXPECT_EQ(list.length(), 0);
    EXPECT_EQ(list.Empty(), true);

    LinkedList<int> list2{1, 2, 3, 4};
    EXPECT_EQ(list2.length(), 4) << "list = " << list << "\n";
    EXPECT_EQ(list2[0], 1);
    EXPECT_EQ(list2[1], 2);
    EXPECT_EQ(list2[2], 3);
    EXPECT_EQ(list2[3], 4);
}

TEST(LinkedListTest, PushAndPop) {
    LinkedList<int> list;

    list.PushBack(1);
    list.PushBack(2);
    list.PushBack(3);

    EXPECT_EQ(list.length(), 3);
    EXPECT_EQ(list.Empty(), false);
    EXPECT_EQ(list[0], 1);
    EXPECT_EQ(list[1], 2);
    EXPECT_EQ(list[2], 3);

    list.PushFront(-1);
    list.PushFront(-2);
    list.PushFront(-3);

    EXPECT_EQ(list.length(), 6);
    EXPECT_EQ(list[0], -3);
    EXPECT_EQ(list[1], -2);
    EXPECT_EQ(list[2], -1);
    EXPECT_EQ(list[3], 1);

    auto front = list.PopFront();
    EXPECT_EQ(front, -3);
    EXPECT_EQ(list.length(), 5);
    EXPECT_EQ(list[0], -2);

    auto back = list.PopBack();
    EXPECT_EQ(back, 3);
    EXPECT_EQ(list.length(), 4);
    EXPECT_EQ(list[3], 2);
}

TEST(LinkedListTest, InsertAndRemove) {
    LinkedList<int> list;

    list.PushBack(1);
    list.PushBack(2);
    list.PushBack(3);
    list.Insert(1, 4);  // 1,4,2,3
    EXPECT_EQ(list[1], 4) << "list: " << list;
    list.Insert(3, 5);  // 1,4,2,5,3
    EXPECT_EQ(list[3], 5) << "list: " << list;

    list.Remove(0);  // 4,2,5,3
    EXPECT_EQ(list[0], 4) << "list: " << list;
    list.Remove(2);  // 4,2,3
    EXPECT_EQ(list[2], 3) << "list: " << list;

    list.Clear();
    EXPECT_EQ(list.length(), 0);
    EXPECT_EQ(list.Empty(), true);
}
